# views.py
import json
import sys
import traceback

import pandas as pd
from django.core.exceptions import ValidationError
from django.db import transaction, IntegrityError
from django.http import HttpResponseRedirect, JsonResponse, FileResponse
from django.shortcuts import render, redirect
from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.hashers import check_password, make_password
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods

from interview.models import InterviewRecord
from user.models import CustomUser, UserToken


# 普通用户登录
@csrf_exempt
def user_login(request):
    error_msg = "登录成功！"
    if request.method == 'POST':
        try:
            data = json.loads(request.body)
            account = data['account']
            password = data['password']

            if not all([account, password]):
                error_msg = "账号和密码不能为空"
                return JsonResponse({"message": error_msg, "code": 0})

            user = authenticate(account=account, password=password)
            if user and check_password(password, user.password):
                if not user.is_enabled:
                    error_msg = "该账号已被禁用"
                    return JsonResponse({"message": error_msg, "code": 0})

                try:
                    token = UserToken.generate_token(user)
                    return JsonResponse({"message": error_msg, "code": 1, "token": token,"user":{"id":user.id,"account":user.account,"user_name":user.user_name}})
                except IntegrityError:
                    # 处理极端并发场景（如 update_or_create 未覆盖）
                    token = UserToken.objects.get(user=user)
                    return JsonResponse({"message": error_msg, "code": 1, "token": token,"user":{"id":user.id,"account":user.account,"user_name":user.user_name}})
            else:
                error_msg = "账号或密码错误！"
                return JsonResponse({"message": error_msg, "code": 0})
        except json.JSONDecodeError:
            error_msg = "请求数据格式错误"
            return JsonResponse({"message": error_msg, "code": 0})


# 新增用户
@csrf_exempt
@require_http_methods(["POST"])  # 限制仅允许 POST 请求
def create_user(request):
    # 解析 JSON 数据
    try:
        auth_header = request.headers.get("Authorization", "")
        token = UserToken.objects.get(key=auth_header)
        if not token.user.is_authenticated:
            return JsonResponse({"message": "未登录"}, status=401)
        data = json.loads(request.body)
    except UserToken.DoesNotExist:
        return JsonResponse({'status': 'error', 'message': '用户授权未通过'}, status=400)
    except json.JSONDecodeError:
        return JsonResponse({'code': 400, 'msg': '无效的 JSON 格式'}, status=400)

    # 必填字段校验
    required_fields = ['account', 'password', 'user_name']
    for field in required_fields:
        if field not in data or not data[field].strip():
            return JsonResponse({'code': 400, 'msg': '%s 为必填字段'%{field}}, status=400)

    # 性别选项校验
    if 'gender' in data and data['gender'] not in [1, 2, 3]:
        return JsonResponse({'code': 400, 'msg': '性别参数无效'}, status=400)

    # 构建用户数据
    user_data = {
        'account': data['account'].strip(),
        'password': make_password(data['password']),  # 密码加密
        'user_name': data['user_name'].strip(),
        'gender': data.get('gender', 3),  # 默认性别为其他
        'major_class': data.get('major_class', '').strip(),
        'quota': data.get('quota', 0)
    }

    # 创建用户
    try:
        new_user = CustomUser.objects.create(**user_data)
        return JsonResponse({
            'code': 201,
            'msg': '用户创建成功',
            'data': {
                'id': new_user.id,
                'account': new_user.account,
                'created_at': new_user.created_at.strftime("%Y-%m-%d %H:%M:%S")
            }
        }, status=201)

    except Exception as e:
        # 处理唯一性约束错误
        if 'account' in str(e).lower():
            return JsonResponse({'code': 400, 'msg': '账号已存在'}, status=400)
        return JsonResponse({'code': 500, 'msg': '服务器错误: %s'}%{str(e)}, status=500)

# 退出登录
def user_logout(request):
    auth_header = request.headers.get("Authorization", "")
    s = UserToken.logout_by_token(auth_header)
    return JsonResponse({"code": 1})

# 批量导入
@csrf_exempt
def import_users_from_excel(request):
    if request.method == 'POST' and request.FILES.get('excel_file'):
        excel_file = request.FILES['excel_file']
        result = {'total': 0, 'success': 0, 'errors': []}

        try:
            # auth_header = request.headers.get("Authorization", "")
            # token = UserToken.objects.get(key=auth_header)
            # if not token.user.is_authenticated:
            #     return JsonResponse({"message": "未登录"}, status=401)
            # 在视图开头添加
            MAX_FILE_SIZE = 10 * 1024 * 1024  # 10MB
            if excel_file.size > MAX_FILE_SIZE:
                return JsonResponse({'code': 400, 'message': "文件大小超过限制"})

            # 读取 Excel 文件
            df = pd.read_excel(excel_file)
            df = df.where(pd.notnull(df), None)  # 将 NaN 转换为 None

            # 列名映射（允许中文列名）
            column_mapping = {
                '账号': 'account',
                '密码': 'password',
                '姓名': 'user_name',
                '性别': 'gender',
                '专业班级': 'major_class',
                '配额': 'quota'
            }
            df.rename(columns=column_mapping, inplace=True)

            # 必须存在的字段
            required_fields = ['account', 'password', 'user_name']

            with transaction.atomic():
                for index, row in df.iterrows():
                    result['total'] += 1
                    row_data = row.to_dict()

                    try:
                        # 基础校验
                        missing_fields = [field for field in required_fields if not row_data.get(field)]
                        if missing_fields:
                            raise ValidationError("缺少必填字段: %s"%{', '.join(missing_fields)})

                        # 性别处理
                        gender_mapping = {'男': 1, '女': 2, '其他': 3}
                        raw_gender = str(row_data.get('gender', '')).strip()
                        row_data['gender'] = gender_mapping.get(raw_gender, 3)

                        # 密码处理
                        raw_password = str(row_data['password'])
                        if len(raw_password) < 6:
                            raise ValidationError("密码长度不能小于6位")
                        row_data['password'] = make_password(raw_password)

                        # 默认值处理
                        row_data.setdefault('quota', 0)

                        # 创建用户
                        CustomUser.objects.create(
                            account=row_data['account'],
                            password=row_data['password'],
                            user_name=row_data['user_name'],
                            gender=row_data['gender'],
                            major_class=row_data.get('major_class'),
                            quota=row_data['quota']
                        )
                        result['success'] += 1

                    except Exception as e:
                        exc_type, exc_value, exc_traceback = sys.exc_info()
                        # 提取最后一个堆栈帧（即错误发生的具体位置）
                        stack_summary = traceback.extract_tb(exc_traceback)[-1]
                        print(stack_summary)
                        error_msg = "第 %s 行学生已存在或格式错误"%(index+1)
                        result['errors'].append(error_msg)
                        print(result['errors'])
                        continue

            return JsonResponse({
                'code': 200,
                'message': "成功导入 %s/%s 条数据"%(result['success'],result['total']),
                'errors': result['errors']
            })
        except UserToken.DoesNotExist:
            return JsonResponse({'status': 'error', 'message': '用户授权未通过'}, status=400)
        except Exception as e:
            exc_type, exc_value, exc_traceback = sys.exc_info()
            # 提取最后一个堆栈帧（即错误发生的具体位置）
            stack_summary = traceback.extract_tb(exc_traceback)[-1]
            print(stack_summary)
            return JsonResponse({
                'code': 500,
                'message': "文件处理失败: %s"%{str(e)}
            }, status=500)

    return JsonResponse({
        'code': 400,
        'message': "请上传有效的 Excel 文件"
    }, status=400)

# 测试
@csrf_exempt
def test(request):
    print(make_password("123456"))
    print(make_password("123456"))
    print(check_password("123456", "pbkdf2_sha256$870000$caO3hgZsEiyBSPa7Q3yVxK$GLmsrtGTV9pf0tJHxAhXsSAKyb2ogLOw6JnBYdc+HII="))  # 输出 True
    return render(request,'import_users.html')

# 下载模板
def download_template(request):
    return FileResponse(open('static/user_template.xlsx', 'rb'), as_attachment=True)


from django.core.paginator import Paginator, EmptyPage
from django.http import JsonResponse
from .models import CustomUser  # 根据实际项目结构调整导入路径

# 查询用户列表
def user_list(request):
    # 获取分页参数并设置默认值
    page = int(request.GET.get('page', 1))
    page_size = int(request.GET.get('page_size', 10))

    # 获取排序后的查询集（按创建时间倒序）
    users = CustomUser.objects.all().order_by('-created_at')

    # 初始化分页器
    paginator = Paginator(users, page_size)

    try:
        current_page = paginator.page(page)
    except EmptyPage:
        # 如果页码超出范围，返回最后一页
        current_page = paginator.page(paginator.num_pages)

    # 序列化用户数据
    serialized_users = []
    for user in current_page:
        serialized_users.append({
            'account': user.account,
            'user_name': user.user_name,
            'is_enabled': user.is_enabled,
            'created_at': user.created_at.strftime('%Y-%m-%d %H:%M:%S'),
            'quota': user.quota,
            'major_class': user.major_class,
            'gender': user.get_gender_display(),  # 获取选项显示值
            'interview_count': user.interview_count
        })

    # 构造响应数据
    response_data = {
        'status': 'success',
        'count': paginator.count,
        'page': current_page.number,
        'total_pages': paginator.num_pages,
        'results': serialized_users
    }

    return JsonResponse(response_data)

# 根据企业id查询预约用户
@csrf_exempt
def get_Users_by_companyAndUserInfo(request):
    company_id = request.GET.get('company_id')
    try:
        # 获取去重后的用户ID列表
        user_ids = InterviewRecord.objects.filter(
            company_id=company_id
        ).values_list('user_id', flat=True).distinct()
        users = CustomUser.objects.filter(id__in=user_ids).select_related()
        # 构建响应数据
        user_list = []
        for user in users:
            # 获取最近一次面试时间
            user_list.append({
                "id": user.id,
                "account": user.account,
                "name": user.user_name,
                "gender": user.get_gender_display(),
                "quota": user.quota,
                "interview_count": user.interview_count,
                "major_class": user.major_class
            })
        # 查询专业列表
        major_class_list = CustomUser.objects.exclude(
            major_class__isnull=True
        ).exclude(
            major_class__exact=''
        ).values_list(
            'major_class', flat=True
        ).distinct().order_by('major_class')

        # 转换为Python列表
        major_class_list = list(major_class_list)
        major_class = request.GET.get('major_class',major_class_list[0])
        # 查询未预约学生
        users2 = CustomUser.objects.exclude(id__in=user_ids).filter(major_class=major_class).select_related()
        user_list2 = []
        for user in users2:
            # 获取最近一次面试时间
            user_list2.append({
                "id": user.id,
                "account": user.account,
                "name": user.user_name,
                "gender": user.get_gender_display(),
                "quota": user.quota,
                "interview_count": user.interview_count,
                "major_class": user.major_class
            })
        return JsonResponse({
            'company_id': company_id,
            'user_count': len(user_list),
            'user_ids': list(user_ids),
            'user_list': user_list,
            'user_list2':user_list2,
            'major_class_list':major_class_list
        })
    except Exception as e:
        return JsonResponse(
            {'error': '数据库查询失败'},
            status=500
        )
